/* Vecmath.

   Copyright (C) 2001, 2002, 2003 Stefan Maierhofer.

   Written by Stefan Maierhofer <sm@cg.tuwien.ac.at>

   This file is part of Vecmath.

   Vecmath is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   Vecmath is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Vecmath; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */

using System;

namespace Vecmath
{

    /// <summary>
    /// RGBA.
    /// </summary>
    public struct RGBA
    {

        public RGBA(float r, float g, float b)
        {
            _x = new float[4];
            _x[0] = r;
            _x[1] = g;
            _x[2] = b;
            _x[3] = 1.0f;
        }

        public RGBA(float r, float g, float b, float a)
        {
            _x = new float[4];
            _x[0] = r;
            _x[1] = g;
            _x[2] = b;
            _x[3] = a;
        }

        public float this [int index]
        {
            get { return _x[index]; }
            set { _x[index] = value; }
        }

        public float r
        {
            get { return _x[0]; }
            set { _x[0] = value; }
        }

        public float g
        {
            get { return _x[1]; }
            set { _x[1] = value; }
        }

        public float b
        {
            get { return _x[2]; }
            set { _x[2] = value; }
        }

        public float a
        {
            get { return _x[3]; }
            set { _x[3] = value; }
        }

        public static RGBA operator+(RGBA v, float f)
        {
            return new RGBA(v[0] + f, v[1] + f, v[2] + f, v[3] + f);
        }

        public static RGBA operator+(RGBA v, RGBA w)
        {
            return new RGBA(v[0] + w[0], v[1] + w[1], v[2] + w[2], v[3] + w[3]);
        }

        public static RGBA operator-(RGBA v, float f)
        {
            return new RGBA(v[0] - f, v[1] - f, v[2] - f, v[3] - f);
        }

        public static RGBA operator-(RGBA v, RGBA w)
        {
            return new RGBA(v[0] - w[0], v[1] - w[1], v[2] - w[2], v[3] - w[3]);
        }

        public static RGBA operator*(RGBA v, float f)
        {
            return new RGBA(v[0] * f, v[1] * f, v[2] * f, v[3] * f);
        }

        public static RGBA operator/(RGBA v, float f)
        {
            return new RGBA(v[0] / f, v[1] / f, v[2] / f, v[3] / f);
        }

        public void Clamp()
        {
            if (_x[0] < 0) _x[0] = 0;
            else if (_x[0] > 1) _x[0] = 1;

            if (_x[1] < 0) _x[1] = 0;
            else if (_x[1] > 1) _x[1] = 1;

            if (_x[2] < 0) _x[2] = 0;
            else if (_x[2] > 1) _x[2] = 1;

            if (_x[3] < 0) _x[3] = 0;
            else if (_x[3] > 1) _x[3] = 1;
        }

        public RGBA Clamped
        {
            get
            {
                RGBA result = this;
                result.Clamp();
                return result;
            }
        }

        public float SquaredLength
        {
            get
            {
                return _x[0] * _x[0] + _x[1] * _x[1] + _x[2] * _x[2] + _x[3] * _x[3];
            }
        }

        public float Length
        {
            get
            {
                return (float)Math.Sqrt(
                    _x[0] * _x[0] + _x[1] * _x[1] + _x[2] * _x[2] + _x[3] * _x[3]
                    );
            }
        }

        public static implicit operator float[](RGBA c)
        {
            return c._x;
        }

        internal float [] _x;

    }
    
  

}
